#!usr/bin/env python3

# 进度 http://ciniao.legu.cc/article.php?id=14 2016年11月28日20:57:01
import os
#twisted默认用的是select()模式会限制客户端的并发数 下面解除这个限制
print(os.name)
if os.name!='nt':
    from twisted.internet import epollreactor
    epollreactor.install()    
else:
    from twisted.internet import iocpreactor
    iocpreactor.install() # 需要安装  pywin32-220.win-amd64-py3.5.exe service_identity

from twisted.internet.protocol import Factory,Protocol
from twisted.internet import reactor
from config import HOST,PORT
from SocketManager import sockManager
from packUtils import packData,unpackData,getHeaderSize
import struct

class GameSocket(Protocol):
    def __init__(self,*args,**kwargs):
        super(GameSocket,self).__init__(*args,**kwargs)
        self.headSize = getHeaderSize()
        self.buffData = bytes()
        print("包头长度self.headSize=",self.headSize,self.buffData)
        
    #有新用户连接至服务器
    def connectionMade(self):
        print('New Client No. =',self.transport.sessionno) #self.transport.sessionno 可以记录当前的客户端id
        sockManager.addClient(self)        
    
    #客户端断开连接
    def connectionLost(self,reason):
        print('Lost Client')
        sockManager.delClient(self)
        
    def translateData(self,data):
        #print('translateData=',type(data))
        if isinstance(data,bytes):            
            return data.decode('utf-8')
        return data
        
    #收到客户端发送数据
    def dataReceived(self, data):
        print('---------- Get data(原始数据长度):' + str(len(data)))        
        if data is not None:
            self.buffData+=data
            #粘包处理
            counter=0
            while True:
                if counter>1000:
                    break
                print('当前接收到的数据长度',str(len(data)),str(data),'包头长度',str(self.headSize))
                if len(data)<self.headSize: #先接收包头
                    print("包头没接收完...")
                    break
                dataLen = data[1] #整个数据的长度
                if len(self.buffData)<dataLen: #接收所有数据
                    print("数据没接收完...")
                    break                
                data = self.buffData #数据接收完成                
                self.buffData = self.buffData[dataLen:] #清空包等待下一个数据包                
                id = 1
                target = sockManager.getClient(id)        
                data = unpackData(data)
                print('---------- Get data:---- 解包后unpackData',data)
                data = list(map(self.translateData,data))
                data = list(map(lambda x:str(x),data)) #这里是临时设置 推送字符串给flash客户端直接显示      
                #向该客户端发送数据
                revData = ' '.join(data)
                #revData = data.decode('utf-8')
                msg = '--from python--: I got your msg;'+ revData +";id="+str(sockManager.getSocketId(self))
                msg = msg.encode('utf-8')
                if target is not None: #有聊天对象
                    target.transport.write(msg)
                else:
                    self.transport.write(msg)
                self.buffData = self.buffData[len(self.buffData):] #清空包等待下一个数据包        
                break
        
        
        
if __name__=='__main__':
    f = Factory()
    f.protocol = GameSocket
    reactor.listenTCP(PORT,f)
    print('server started on ',PORT)
    reactor.run()

    